import React, { useCallback, useRef } from 'react';
import { types, unprotect, onPatch, getSnapshot } from "mobx-state-tree";
import { observer, useLocalStore, useObserver } from 'mobx-react';
import { autorun, runInAction, spy } from 'mobx';

// declaring the shape of a node with the type `Todo`
const Todo = types.model({
  title: types.string,
  done: true,
}).views(self => ({
  get longName() {
    return self.title + '_long...';
  }
})).actions(self => ({
  toggle() {
    self.done = !self.done;
  },
}));

const TodoStore = types.model({
  todos: types.array(Todo)
}).views(self => ({
  get completedCount() {
    return self.todos.filter(todo => todo.done).length;
  },
})).actions(self => ({
  setUndoneByTodoId(id: number) {
    self.todos[id].done = false;
  }
}));

const todoStore = TodoStore.create({
  todos: [
    { title: 'todo1' },
    { title: 'todo2' },
    { title: 'todo3', done: false },
  ]
});

unprotect(todoStore);

autorun(() => {
  console.log('todoStore.completedCount', todoStore.completedCount);
});

onPatch(todoStore, (patch) => console.log('patch', patch));

runInAction(() => {
  todoStore.todos[1].done = false;
  todoStore.todos[1].title = 'abc';
});
// todoStore.setUndoneByTodoId(1);

// creating a tree based on the "Todo" type, with initial data:
const coffeeTodo = Todo.create({
  title: "Get coffee",
  done: true,
});

console.log(coffeeTodo.longName);

export default function MST2() {
  const todo = useLocalStore(() => Todo.create({ title: '自定义监控' }));
  return useObserver(() => (
    <div>
      <div onClick={todo.toggle}>{todo.longName} {todo.done ? '完成' : '进行中...'}</div>
      <div onClick={() => todoStore.setUndoneByTodoId(2)}>{todoStore.completedCount}</div>
      <pre>{JSON.stringify(getSnapshot(todoStore), null, 2)}</pre>
    </div>
  ));
}

function expr() {
  spy((event) => {
    if (event.type === 'action') {
      console.log(`${event.name} with args: ${event.arguments}`)
    }
    console.dir(event);
  });
}

if (module.hot) {
  console.log('module.hot', module.hot.data);
  if (module.hot.data && module.hot.data.store) {
    applySnapshot(todoStore, module.hot.data.store);
  }
  module.hot.dispose((data) => {
    console.log('hot.dispose', data);
    data.store = getSnapshot(todoStore);
  });
}
